//
//  DataDownloader.m
//  DataDownloader
//
//  Created by Brennan Stehling on 10/23/09.
//  Copyright 2009 SmallSharpTools LLC. All rights reserved.
//

#import "DataDownloader.h"


@implementation DataDownloader

@synthesize connection		= _connection;
@synthesize mutableString	= _mutableString;
@synthesize delegate		= _delegate;

- (void)downloadData:(NSString *)urlStr delegate:(id)delegate {
	self.delegate = delegate;
	
    NSLog(@"urlStr = %@", urlStr);
	
	NSURL *url = [[NSURL alloc] initWithString:urlStr];
	NSURLRequest *request;
    
    assert(self.connection == nil); // don't tap receive twice in a row!
	
	// Open a connection for the URL.
	request = [NSURLRequest requestWithURL:url];
	assert(request != nil);
	
	self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
	assert(self.connection != nil);
	
	[url release];
}

- (BOOL)isReceiving
{
    return (self.connection != nil);
}

- (void)_stopReceiveWithStatus:(NSString *)statusString
// Shuts down the connection and displays the result (statusString == nil) 
// or the error status (otherwise).
{
    if (self.connection != nil) {
        [self.connection cancel];
        self.connection = nil;
    }
	
	if (statusString != nil) {
		// report that the download failed
		if([[self delegate] respondsToSelector:@selector(downloadFailed:)]) {
			[[self delegate] downloadFailed:statusString];
		}
	}
}

- (void)connection:(NSURLConnection *)theConnection didReceiveResponse:(NSURLResponse *)response
// A delegate method called by the NSURLConnection when the request/response 
// exchange is complete.
{
#pragma unused(theConnection)
    NSHTTPURLResponse * httpResponse;
	
    assert(theConnection == self.connection);
    
    httpResponse = (NSHTTPURLResponse *) response;
    assert( [httpResponse isKindOfClass:[NSHTTPURLResponse class]] );
    
    if ((httpResponse.statusCode / 100) != 2) {
        [self _stopReceiveWithStatus:[NSString stringWithFormat:@"HTTP error %zd", (ssize_t) httpResponse.statusCode]];
    }
}

- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data
// A delegate method called by the NSURLConnection as data arrives.  We just 
// append the data to an NSMutableString.
{
#pragma unused(theConnection)
    assert(theConnection == self.connection);
   
	// allocate the instance variable (retain until dealloc)
	if (_mutableString == nil){
		_mutableString = [[NSMutableString alloc] init];
	}
	
	NSString* str = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
	
	[self.mutableString appendString:str];
	
//	NSLog(@"str length: %d, %d", [str length], [self.mutableString length]);
	
	[str release];
}

- (void)connection:(NSURLConnection *)theConnection didFailWithError:(NSError *)error
// A delegate method called by the NSURLConnection if the connection fails. 
// We shut down the connection and display the failure.
{
#pragma unused(theConnection)
#pragma unused(error)
    assert(theConnection == self.connection);
    
    [self _stopReceiveWithStatus:@"Connection failed"];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)theConnection
// A delegate method called by the NSURLConnection when the connection has been 
// done successfully.
{
#pragma unused(theConnection)
    assert(theConnection == self.connection);
    
    [self _stopReceiveWithStatus:nil];
	
	NSLog(@"NSMutableString Length: %d", [self.mutableString length]);
	
	// call the downloadFinished delegate (callback)
	if([[self delegate] respondsToSelector:@selector(downloadFinished:)]) {
		[[self delegate] downloadFinished:self.mutableString];
	}
}

- (void) dealloc {
	[_mutableString release];
	[super dealloc];
}

@end
